﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PessModel;
using System.Web.Security;
using PessMvc.Models;
using PessMvc.Helpers;
using System.Data;
using System.IO;
using LinqToExcel;
using LinqToExcel.Domain;
using PessMvc.Lib;
using DoddleReport;
using DoddleReport.Web;
using System.Globalization;
using System.Resources;
using System.Collections;

namespace PessMvc.Controllers
{
    [Authorize]
    public class ExpertJudgeController : Controller
    {
        PessModel.PESSEntities db;
        //
        // GET: /ExpertJudge/
        public ExpertJudgeController()
        {
            db = new PessModel.PESSEntities();
        }
        //public ActionResult Index()
        //{
        //    return View();
        //}

        public ActionResult Create(int expertGroupID)
        {
            ViewBag.ExpertGroupID = expertGroupID;

            //Generate Expert SerialNumber
            var group=db.ExpertGroups.Find(expertGroupID);
            //expert.SerialNumber = GetExpertSerialNumber(group.SubjectID);
            ExpertJudge expJudge = new ExpertJudge();
            expJudge.SerialNumber = GetExpertSerialNumber(group.SubjectID);

            ViewBag.ExpertGroupCallsign = group.Callsign;
            ViewBag.ActivityID = group.Subject.ActivityID;
            ViewBag.Gender = Utility.GenderSelectList(true);
            return View(expJudge);
        }

        [HttpPost]
        public ActionResult Create(ExpertJudge expert)
        {
            //expert.Password = "111111";
            if (ModelState.IsValid)
            {
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                string errorMsg="";
                if (ibl.Add(expert, out errorMsg) == true)
                {
                    return RedirectToAction("Details", "ExpertGroup", new { id = expert.ExpertGroupID });
                }
                else
                {
                    ModelState.AddModelError("", errorMsg);
                }
                //MembershipCreateStatus createStatus;
                //MembershipUser user = Membership.CreateUser(expert.SerialNumber, "111111", expert.Email, "question", "answer", true, null, out createStatus);
                //if (createStatus == MembershipCreateStatus.Success)
                //{
                //    Roles.AddUserToRole(user.UserName, "ExpertJudge");
                //    expert.UserID = new Guid(user.ProviderUserKey.ToString());

                //    db.ExpertJudges.Add(expert);
                //    db.SaveChanges();
                //    return RedirectToAction("Details", "ExpertGroup", new { id = expert.ExpertGroupID });
                //}
                //else
                //{
                //    ModelState.AddModelError("", createStatus.ToString());
                //}
            }

            ViewBag.ExpertGroupID = expert.ExpertGroupID;
            var group = db.ExpertGroups.Find(expert.ExpertGroupID);
            ViewBag.ExpertGroupCallsign = group.Callsign;
            ViewBag.ActivityID = group.Subject.ActivityID;
            ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
            return View(expert);
        }

        [HttpPost]
        public ActionResult AddExpertJudges(HttpPostedFileBase file, int activityID)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                // extract only the fielname
                var fileName = Path.GetFileName(file.FileName);
                // store the file inside ~/App_Data/uploads folder
                var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(path);


                var excel = new ExcelQueryFactory(path);
                //excel.FileName = ;
                excel.DatabaseEngine = DatabaseEngine.Ace;
                excel.AddMapping<ExpertJudgeModel>(m => m.ExpertGroupID, "评委组ID");
                excel.AddMapping<ExpertJudgeModel>(m => m.RealName, "真实姓名");
                excel.AddMapping<ExpertJudgeModel>(m => m.Email, "email地址");
                excel.AddMapping<ExpertJudgeModel>(m => m.Password, "初始密码");
                excel.AddMapping<ExpertJudgeModel>(m => m.Phone, "电话");
                var members = from m in excel.Worksheet<ExpertJudgeModel>()
                              select m;

                string errorMsg = "";
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                foreach (var x in members)
                {
                    if (ibl.IfExpertExists(x.ExpertGroupID, x.RealName) == false&&ibl.IfExpertGroupMatchesActivity(activityID,x.ExpertGroupID))
                    {
                        ExpertJudge expert = new ExpertJudge() { 
                            SerialNumber=CalculateSerialNumber(x.ExpertGroupID),
                            Email = x.Email,
                            ExpertGroupID = x.ExpertGroupID, 
                            RealName = x.RealName, 
                            Phone = x.Phone };
                        if (ibl.Add(expert, out errorMsg, x.Password) == false) //Once error is encounted, stop adding remaining experts. Show error message.
                        {
                            throw new Exception(errorMsg);                            
                        }
                    }
                }
            }

            // redirect back to the index action to show the form once again
            return RedirectToAction("Index", new { activityID = activityID });  
        }
        private string CalculateSerialNumber(int? expertGroupID)
        {
            return GetExpertSerialNumber(db.ExpertGroups.Find(expertGroupID).SubjectID);
        }
        private string GetExpertSerialNumber(int? subjectID)
        {
            int activityID = db.Subjects.Find(subjectID).ActivityID;

            int expertCount = (from e in db.ExpertJudges
                               where e.ExpertGroup.Subject.ID == subjectID && e.ExpertGroup.Subject.ActivityID == activityID
                               select e).Count();

            return string.Format("A{0}S{1}PW{2}", activityID, subjectID, expertCount);
        }
        public ActionResult Index(int activityID,int? expertGroupID)
        {
            var experts=db.ExpertJudges.Where(e => e.ExpertGroup.Subject.ActivityID == activityID);
            if (expertGroupID != null)
            {
                experts = experts.Where(e => e.ExpertGroupID == expertGroupID);
            }

            var expertModels = experts.ToList().ToExpertJudgeModelList();
            //var expertModels = new List<ExpertJudgeModel>();            
            //foreach(var e in experts)
            //{
            //    expertModels.Add(e.ToExpertJudgeModel());
            //}

            ViewBag.ActivityID = activityID;
            ViewBag.ExpertGroupID=new SelectList(db.ExpertGroups.Where(g=>g.Subject.ActivityID==activityID),"ID","Callsign");
            return View(expertModels);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName">SerialNumber</param>
        /// <returns></returns>
        [Authorize(Roles="Admin,ExpertJudge")]
        public ActionResult Edit(string serialNumber,string returnUrl)
        {
            if (Utility.IsCurrentUserExpertHimself(serialNumber)||Roles.IsUserInRole("Admin"))
            {
                var expert = db.ExpertJudges.Find(serialNumber); expert.Email = Membership.GetUser(serialNumber).Email;
                ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
                ViewBag.ReturnUrl = returnUrl;
                return View(expert);
            }
            else
            {
                throw new Exception("Not authorized.");
            }
        }
        [HttpPost]
        public ActionResult Edit(ExpertJudge expertJudge,string returnUrl)
        {
            if (ModelState.IsValid)
            {
                db.Entry(expertJudge).State = EntityState.Modified;
                db.SaveChanges();
                var user = Membership.GetUser(expertJudge.SerialNumber);
                user.Email = expertJudge.Email;
                Membership.UpdateUser(user);                

                return Go2ReturnUrl(returnUrl);//Redirect(returnUrl);
            }
            else
            {
                ViewBag.Gender = Utility.GenderSelectList(expertJudge.Gender);
                return View(expertJudge);
            }

        }

        public ActionResult Go2ReturnUrl(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Activity");
            }
        }

        public ActionResult Delete(string serialNumber, string returnUrl)
        {
            ExpertJudge expert = db.ExpertJudges.Find(serialNumber);
            ViewBag.ReturnUrl = returnUrl;
            if (expert == null)
            {
                return HttpNotFound();
            }
            return View(expert);
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(string serialNumber, string returnUrl)
        {
            ExpertJudge expert = db.ExpertJudges.Find(serialNumber);
            ViewBag.ReturnUrl = returnUrl;
            int expertGroupID=(int)expert.ExpertGroupID;
            if (expert.Scores.Count!=0)
            {
                ModelState.AddModelError("", "该评委已经评分，不能删除！");
            }
            else if (!Membership.DeleteUser(serialNumber))
            {
                ModelState.AddModelError("", "该用户无法删除！请联系系统管理员。");
            }
            else
            {
                db.ExpertJudges.Remove(expert);
                db.SaveChanges();
                //return RedirectToAction("Details", "ExpertGroup", new {id=expertGroupID });
                return Go2ReturnUrl(returnUrl);
            }            
                
            return View(expert);            
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult ExportToExcel(int activityID)
        {
            //var query = db.GetArchiveList(activityID).AsEnumerable();//db.Archives.Where(a => a.Subject.ActivityID == activityID);

            //return CreateReport(query,new DoddleReport.Writers.ExcelReportWriter(), selectedProperties);
            var query = db.GetExpertJudges(activityID);//db.ExpertJudges.Where(e => e.ExpertGroup.Subject.ActivityID == activityID);
            //var expertModels = experts.ToList().ToExpertJudgeModelList();
            //string subTitle = string.Format("{0}:{1}", subject != null ? subject.Name : "", activity.Name);
            var report = new DoddleReport.Report(query.ToReportSource());
            for (int i = 0; i < report.DataFields.Count; i++)
            {
                report.DataFields[i].HeaderText = Utility.Translate<PessResources.ExpertJudge>(report.DataFields[i].Name);
            }
            IReportWriter writer = new DoddleReport.Writers.ExcelReportWriter();
            return new ReportResult(report, writer, "application/vnd.ms-excel") { FileName = HttpUtility.UrlPathEncode("评委名单.xls") };
        }
       
    }
}
